package com.example.demo.service.impl;

import com.example.demo.dao.TestAsyncMapper;
import com.example.demo.entity.TestAsync;
import com.example.demo.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @author huangke
 * @description 多线程test
 * @date 2020/11/28
 */
@Service("testService")
@Slf4j
public class TestServiceImpl implements TestService {

    @Resource
    private TestAsyncMapper testAsyncMapper;

    private static final List<String> list = Arrays.asList("test10", "test11", "test21", "test31", "test41", "test51", "test61", "test71", "test81", "test91", "test1");
    private static final List<String> list1 = Arrays.asList("test3", "test23", "test43", "test63", "test83", "test93");

    @Override
    @Async
    public CompletableFuture<Integer> testInsert(TestAsync testAsync) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (list.contains(testAsync.getName())) {
            throw new RuntimeException(testAsync.getName() + "error");
        }
        if (list1.contains(testAsync.getName())) {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(testAsync.getName());
        testAsyncMapper.insert(testAsync);
        return CompletableFuture.completedFuture(testAsync.getId().intValue());
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void testTrans() {
        TestAsync testAsync = TestAsync.builder().id(1).name("a").build();
        testAsyncMapper.insert(testAsync);
        if (!testTrans1()) {
            throw new RuntimeException("111");
        }
        testTrans2();
        try {
            testTrans3();
        } catch (Exception e) {
            throw new RuntimeException("555");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    boolean testTrans1() {
        TestAsync testAsync = TestAsync.builder().id(2).name("b").build();
        return testAsyncMapper.insert(testAsync) == 1;
    }

    private boolean testTrans2() {
        TestAsync testAsync = TestAsync.builder().id(3).name("c").build();
        return testAsyncMapper.insert(testAsync) == 1;
    }

    private boolean testTrans3() {
        TestAsync testAsync = TestAsync.builder().id(4).name("d").build();
        if (testAsyncMapper.insert(testAsync) == 1) {
            throw new RuntimeException("4444");
        }
        return true;
    }


    @Override
    @Async
    public CompletableFuture<String> testaaa(Integer i) throws Exception {
        try {
            log.info("开始执行" + i+ Thread.currentThread().getName());
            Thread.sleep(2000);
            if (i % 5 == 0) {
                throw new RuntimeException("哦哦哦哦哦1111" + i);
            }
        } catch (Exception e) {
            throw new RuntimeException("哦哦哦哦哦" + i);
        }
        return CompletableFuture.completedFuture("线程执行" + i);
    }

    @Override
    @Async("firstCustomerExecutor")
    public CompletableFuture<String> testbbb(Integer i) throws Exception {
        try {
            log.info("222开始执行" + i);
            Thread.sleep(2000);
            if (i % 5 == 0) {
                throw new RuntimeException("哦哦哦哦哦1111" + i);
            }
        } catch (Exception e) {
            throw new RuntimeException("哦哦哦2222哦哦" + i);
        }
        return CompletableFuture.completedFuture("线程执行" + i);
    }
}